﻿using EnvDTE;
using EnvDTE80;
using I18nJson.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace I18nJson
{
    public static class Tools
    {
        // 根据json文件的名称得到对应cs源代码的命名空间和类名
        private static bool GetSourceCSFile(string jsonFileName, out string namespaceName, out string className)
        {
            namespaceName = "";
            className = "";
            string fileName = jsonFileName.Replace(".lang.json", ".cs");
            if (!File.Exists(fileName))
                fileName = jsonFileName.Replace(".lang.json", ".xaml.cs");
            if (!File.Exists(fileName))
                return false;
            using (FileStream fs = File.Open(fileName, FileMode.Open, FileAccess.Read))
            using (StreamReader sr = new StreamReader(fs))
            {
                while (true)
                {
                    string line = sr.ReadLine();
                    if (line == null)
                        return false;
                    line = line.Trim();
                    if (line.StartsWith("namespace "))
                    {
                        if (namespaceName == "")
                            namespaceName = line.Replace("namespace", "").Trim();
                    }
                    else if (line.Contains(" class "))
                    {
                        if (className == "")
                        {
                            className = line.Substring(line.IndexOf(" class ") + " class ".Length).Trim();
                            if (className.Contains(":"))
                            {
                                className = className.Substring(0, className.IndexOf(':')).Trim();
                            }
                        }
                    }
                    if (namespaceName != "" && className != "" && !namespaceName.Contains(" ") && !className.Contains(" "))
                        return true;
                }
            }
        }

        public static Dictionary<string, string> GenerateXaml(string template, string jsonFullFileName)
        {
            Dictionary<string, string> dic = new Dictionary<string, string>();

            string json = "";
            using (FileStream fs = File.Open(jsonFullFileName, FileMode.Open, FileAccess.Read))
            using (StreamReader sr = new StreamReader(fs, Encoding.UTF8))
            {
                json = sr.ReadToEnd();
            }
            LanguageConfig config = JsonConvert.DeserializeObject<LanguageConfig>(json);
            if (config == null)
                return dic;

            for (int langIndex = 0; langIndex < config.Langs.Length; langIndex++)
            {
                string xamlStr = template;
                for (int varIndex = 0; varIndex < config.Vars.Length; varIndex++)
                {
                    xamlStr = Tools.InsertBeforeLabel(xamlStr, @"</ResourceDictionary>", $"    <sys:String x:Key=\"{config.Vars[varIndex].Name}\">{config.Vars[varIndex].Texts[langIndex]}</sys:String>{Environment.NewLine}");
                }
                dic.Add(config.Langs[langIndex], xamlStr);
            }
            return dic;
        }

        public static string GenerateCS(string template, string jsonFullFileName)
        {
            if (!GetSourceCSFile(jsonFullFileName, out string namespaceName, out string className))
                return null;
            string csTemplate = GetTemplate(template, "[__FileTemplateStart__]", "[__FileTemplateEnd__]");
            string varTemplate = GetTemplate(template, "[__VariableTemplateStart__]", "[__VariableTemplateEnd__]");
            string caseTemplate = GetTemplate(template, "[__CaseTemplateStart__]", "[__CaseTemplateEnd__]");
            LanguageConfig config = GetLanguageConfig(jsonFullFileName);
            string csStr = csTemplate.Replace("[__namespaceReplace__]", namespaceName).Replace("[__classNameReplace__]", className);
            for (int i = config.Vars.Length - 1; i >= 0; i--)
            {
                // 生成变量
                string varString = varTemplate.Replace("[__variableNameReplace__]", config.Vars[i].Name);
                for (int j = config.Langs.Length - 1; j >= 0; j--)
                {
                    // 生成case语句
                    string caseStr = caseTemplate.Replace("[__langCodeReplace__]", config.Langs[j]);
                    caseStr = caseStr.Replace("[__textReplace__]", config.Vars[i].Texts[j]);

                    // 向变量中插入case语句
                    varString = InsertAfterLabel(varString, "[__caseInsert__]", caseStr);
                }

                // 向模板中插入变量
                csStr = InsertAfterLabel(csStr, "[__variableInsert__]", varString);
            }
            return csStr;
        }

        public static string GetWholeXamlTemplate()
        {
            // 获取当前程序集
            Assembly assembly = Assembly.GetExecutingAssembly();

            // 读取资源文件为流
            using (Stream stream = assembly.GetManifestResourceStream(assembly.GetName().Name + ".Templates.ResourceDicTemplate.txt"))
            using (StreamReader reader = new StreamReader(stream))
            {
                // 读取文本
                string result = reader.ReadToEnd();

                // 输出或使用文本
                //Console.WriteLine(result);
                return result;
            }
        }

        public static string GetWholeCSTemplate()
        {
            // 获取当前程序集
            Assembly assembly = Assembly.GetExecutingAssembly();

            // 读取资源文件为流
            using (Stream stream = assembly.GetManifestResourceStream(assembly.GetName().Name + ".Templates.CSTemplate.txt"))
            using (StreamReader reader = new StreamReader(stream))
            {
                // 读取文本
                string result = reader.ReadToEnd();

                // 输出或使用文本
                //Console.WriteLine(result);
                return result;
            }
        }

        private static string GetTemplate(string template, string startLabel, string endLabel)
        {
            int startIndex = template.IndexOf(startLabel) + startLabel.Length;
            int endIndex = template.IndexOf(endLabel);
            return template.Substring(startIndex, endIndex - startIndex);
        }

        private static string InsertBeforeLabel(string target, string insertLabel, string insertText)
        {
            int startIndex = target.IndexOf(insertLabel);
            return target.Insert(startIndex, insertText);
        }

        private static string InsertAfterLabel(string target, string insertLabel, string insertText)
        {
            int startIndex = target.IndexOf(insertLabel) + insertLabel.Length;
            return target.Insert(startIndex, insertText);
        }

        private static LanguageConfig GetLanguageConfig(string fullFileName)
        {
            using (FileStream fs = File.Open(fullFileName, FileMode.Open, FileAccess.Read))
            using (StreamReader sr = new StreamReader(fs, Encoding.UTF8))
            {
                return JsonConvert.DeserializeObject<LanguageConfig>(sr.ReadToEnd());
            }
        }

        // 获取选中的文件列表
        public static string[] GetSelectedFiles(DTE2 dte2)
        {
            // 获取选中的文件列表
            List<string> selectedFileNames = new List<string>();
            foreach (SelectedItem item in dte2.SelectedItems)
            {
                if (item.ProjectItem != null)
                {
                    selectedFileNames.Add(item.ProjectItem.get_FileNames(0));
                }
            }
            return selectedFileNames.ToArray();
        }

        // 判断项目中是否包含某文件
        public static bool IsContainsFile(Project project, string fileFullName)
        {
            bool containsFile = project.ProjectItems.Cast<ProjectItem>().Any(item => item.FileNames[0].Equals(fileFullName));
            return containsFile;
        }
    }
}
